package features.advance.jdk.io.unblocking;

import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;

/**
 *  非阻塞IO
 *
 * @author LIN
 * @date 2021-07-09
 */
public class Server {

    public static void main(String[] args) throws Exception{
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ServerSocket serverSocket = ssc.socket();

        serverSocket.bind(new InetSocketAddress(8081));
        ssc.configureBlocking(false);
        Selector selector = Selector.open();

        ssc.register(selector, SelectionKey.OP_ACCEPT);

        while (selector.select() > 0){
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            for (SelectionKey key : selectionKeys) {
                if(key.isAcceptable()){
                    ServerSocketChannel server = (ServerSocketChannel) key.channel();
                    SocketChannel sc = server.accept();
                    if(sc == null){
                        continue;
                    }
                    sc.configureBlocking(false);
                    sc.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE);
                }
                if(key.isReadable()){
                    SocketChannel server = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(5000);
                    server.read(buffer);
                    System.out.println(new String(buffer.array()));

                }
                if(key.isWritable()){
                    key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
                    SocketChannel channel = (SocketChannel) key.channel();
                    int writtenedSize = channel.write(ByteBuffer.wrap("接受成功".getBytes()));
                    if(writtenedSize == 0){
                        key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
                    }
                }
            }
            selector.selectedKeys().clear();
        }

    }


}
